#pragma once

#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <vector>
#include "baseClass/Physical.h"

// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
enum Camera_Movement {
    FORWARD,
    BACKWARD,
    LEFT,
    RIGHT
};




// An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
class Camera: public Physical::Loaction
{

private:
    // calculates the front vector from the Camera's (updated) Euler Angles
    void updateCameraVectors();


    // camera Attributes
   
    glm::vec3 Up;
    glm::vec3 Right;
    glm::vec3 WorldUp;

    // camera options
    float MovementSpeed;
    float MouseSensitivity;
    float Zoom;

    glm::mat4 projection;
    glm::vec3 Front;
    
public:
    
    // constructor with vectors
    Camera(float SCR_WIDTH, float SCR_HEIGHT,glm::vec3 position = glm::vec3(0.0f, 2.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 0.0f, 1.0f)) ;
    Camera(float SCR_WIDTH, float SCR_HEIGHT,float posX, float posY, float posZ, float upX, float upY, float upZ) ;

    // returns the view matrix calculated using Euler Angles and the LookAt Matrix
    glm::mat4 GetViewMatrix()
    {
        return glm::lookAt(position, position + Front, Up);
    }

    glm::mat4 GetProjectionMatrix()
    {
        return projection;
    }

    // processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
    void ProcessKeyboard(Camera_Movement direction, float deltaTime);
    // processes input received from a mouse input system. Expects the offset value in both the x and y direction.
    void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true);


};